昨天我們成功建立了一個 nginx 的 Pod,並體驗到 Pod 從建立到 Ready 的過程。輸一行指令就能把 Pod 給跑起來,雖然這個動作看起來很直覺,但是事情並沒有這麼簡單!
想像一下:如果今天不是一個 Pod,而是十個、二十個?如果還需要記住一大堆參數?更慘的是,如果今天要團隊協作的話,靠「打指令」根本沒辦法好好管理。
所以今天我們要透過 YAML,把資源需求寫下來,不僅更容易複製、修改,也能和 Git 做版本控管,甚至 CI/CD 自動化部署,這才是 Kubernetes 的 Best Practice!
在了解 Kubernetes 的 YAML 結構之前,先快速看一下 YAML 的基本語法。其實 YAML 就是由兩種結構組成的:
-
加一個空格作為列表項# 我是註解,以下指令是給 Kubernetes 進行探針檢查行為
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
apiVersion: v1
kind: Pod
👉 YAML 檔案就是由 List 和 Dictionary 混合使用形成的複合結構。
了解完 YAML 檔的語法之後,我們要來看看 Kubernetes 用的 YAML 檔的結構。不管建立什麼資源,都必須包含四個頂層欄位:apiVersion
、kind
、metadata
、spec
。
v1
、apps/v1
、extensions/v1beta1
。對於 Pod 來說,我們用 v1
:apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: my-app
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
把上面四個必要欄位組合起來,就是一個完整的 Pod 定義檔:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: my-app
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
接下來就是透過 kubectl
把 Pod 基於這個 YAML 檔建構起來:
kubectl create -f pod-def.yaml
我們繼續來玩玩看 YAML 檔的變化。還記得昨天提到 Pod 可以放多個 Container 嗎?現在來實際試試看!
回到前面 YAML 語法的部分,我們看到 spec 的 containers 參數是 List 型態,因此只要在下面新增另一個 Container 定義即可:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: my-app
type: front-end
spec:
containers:
- name: nginx-container
image: nginx
# 新增一個 Container
- name: redis-container
image: redis
部署後可以看到 READY 欄位顯示 2/2
,代表兩個 Container 都在運行:
接下來用 describe
查看我們剛剛設定的內容,可以看到對應的 Container 和 Image 名稱:
kubectl describe pods myapp-pod
在實務上,有時候我們不是從零開始寫 YAML,而是接手別人跑好的 Pod,這時就會遇到要修改的情境。假如現在在協作場景,或者接手一個專案,我們需要更新現有的 Pod,但手邊沒有原始的定義檔該怎麼辦?有兩種方式可以處理:
kubectl get pods myapp-pod -o yaml > pod-definition.yaml
這樣就會取得 Pod 的完整定義檔案。如果要更新內容,可以直接修改這個 YAML 檔,然後將原始 Pod 刪除並重新建立。
kubectl edit pods myapp-pod
這個指令會開啟預設編輯器,讓你直接修改 Pod 的定義。修改完成後儲存,Kubernetes 會自動套用變更。
注意:並不是所有 Pod 的設定都可以直接編輯,只有下面列出的屬性是可編輯的。
spec.containers[*].image
spec.initContainers[*].image
spec.activeDeadlineSeconds
spec.tolerations
spec.terminationGracePeriodSeconds
今天我們從命令式轉向聲明式的 YAML 管理方式,這個轉變雖然一開始可能覺得麻煩,但帶來很多的好處:
我們也嘗試在一個 Pod 內運行多個 Container,以及如何編輯或更新現有的 Pod。透過 YAML 檔案,我們可以很清楚地定義 Pod 的四大核心欄位:apiVersion、kind、metadata、spec,每個欄位都有特定的作用和格式要求。
但是現在有個問題:如果我們的應用程式需要高可用性,單一個 Pod 是不夠的。萬一這個 Pod 掛了怎麼辦?萬一流量突然變大需要多個 Pod 分擔負載怎麼辦?總不能一個一個手動建立 Pod 吧?
明天我們要來探討如何使用 ReplicaSet
來解決這些問題,讓 Kubernetes 自動幫我們管理多個 Pod 的副本,確保應用程式的高可用性和擴展性!